21 #define foreach(x, v) for (typeof (v).begin() x = (v).begin(); x != (v).end(); ++x)
22 #define For(i, a, b) for (int i=(a); i<(b); ++i)
23 #define D(x) cout << #x " is " << x << endl
26 Maximum number of edges is around 55*55*2*6*2. There are less than
27 55*55 nodes. We split each node in two (in and out) hence
28 55*55*2. We assume each node is connected to 6 neighbors: 4 partners
29 in the grid plus the source and sink, hence 55*55*2*6. But for each
30 edge there are actually two edges (counting its complementary for
31 the backflow). This is actually and upper bound because I'm too
32 lazy to find out the exact number of edges.
34 const int MAXE
= 55*55*2*6*2;
44 const int oo
= INT_MAX
/ 2 - 1;
46 int add_edge(int u
, int v
, int c
){
47 adj
[current_edge
] = v
;
48 cap
[current_edge
] = c
;
49 next
[current_edge
] = first
[u
];
50 first
[u
] = current_edge
;
53 adj
[current_edge
] = u
;
54 cap
[current_edge
] = 0;
55 next
[current_edge
] = first
[v
];
56 first
[v
] = current_edge
;
60 inline int in(int u
){ return 2*u
; }
61 inline int out(int u
){ return 2*u
+ 1; }
62 inline int number(int r
, int c
){ return r
* cols
+ c
; }
64 void print_edges(int u
){
65 printf("Edges going out from %d:\n", u
);
66 for (int e
= first
[u
]; e
!= -1; e
= next
[e
]){
67 printf("(v = %d, cap = %d)\n", adj
[e
], cap
[e
]);
73 int arrived_by
[MAXE
]; //arrived_by[i] = The last edge that I used to reach node i
74 int find_augmenting_path(int src
, int snk
){
76 Make a BFS to find an augmenting path from the source to the sink.
77 Then pump flow through this path, and return the amount that was pumped.
79 memset(arrived_by
, -1, sizeof arrived_by
);
84 while (h
< t
&& arrived_by
[snk
] == -1){ //BFS
86 for (int e
= first
[u
]; e
!= -1; e
= next
[e
]){
88 if (arrived_by
[v
] == -1 && cap
[e
] > 0){
90 incr
[v
] = min(incr
[u
], cap
[e
]);
96 if (arrived_by
[snk
] == -1) return 0;
101 //Remove capacity from the edge used to reach node "cur"
102 //Add capacity to the backedge
103 cap
[arrived_by
[cur
]] -= neck
;
104 cap
[arrived_by
[cur
] ^ 1] += neck
;
106 cur
= adj
[arrived_by
[cur
] ^ 1]; //move backwards in the path
111 int max_flow(int src
, int snk
){
113 while ((neck
= find_augmenting_path(src
, snk
)) != 0){
122 for(scanf("%d", &cases
); cases
--; ){
124 if (scanf("%d %d %d", &rows
, &cols
, &banks
) != 3) break;
126 int source
= rows
* cols
, sink
= source
+ 1;
128 memset(next
, -1, sizeof next
);
129 memset(first
, -1, sizeof first
);
131 for (int k
=0; k
<banks
; ++k
){
133 scanf("%d %d", &r
, &c
);
135 add_edge(out(number(r
, c
)), in(sink
), 1);
138 for (int i
=0; i
<rows
; ++i
){
139 for (int j
=0; j
<cols
; ++j
){
140 if (i
== 0 || i
== rows
- 1 || j
== 0 || j
== cols
- 1){ //node lies on the border
141 add_edge(out(source
), in(number(i
, j
)), 1);
144 add_edge(out(number(i
, j
)), in(number(i
-1, j
)), 1);
147 add_edge(out(number(i
, j
)), in(number(i
+1, j
)), 1);
150 add_edge(out(number(i
, j
)), in(number(i
, j
-1)), 1);
153 add_edge(out(number(i
, j
)), in(number(i
, j
+1)), 1);
158 for (int i
=0; i
<rows
; ++i
){
159 for (int j
=0; j
<cols
; ++j
){
160 add_edge(in(number(i
, j
)), out(number(i
, j
)), 1);
163 add_edge(in(source
), out(source
), oo
);
164 add_edge(in(sink
), out(sink
), oo
);
167 printf("in nodes:\n");
168 for (int i=0; i<rows; ++i){
169 for (int j=0; j<cols; ++j){
170 print_edges(in(number(i, j)));
173 printf("out nodes:\n");
174 for (int i=0; i<rows; ++i){
175 for (int j=0; j<cols; ++j){
176 print_edges(out(number(i, j)));
180 print_edges(in(source));
181 print_edges(out(source));
183 print_edges(in(sink));
184 print_edges(out(sink));
187 int f
= max_flow(in(source
), out(sink
));
189 printf("%s\n", f
== banks
? "possible" : "not possible");